home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 21
/
Cream of the Crop 21 (Terry Blount) (October 1996).iso
/
comm
/
msged400.zip
/
src
/
dlgbox.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-24
|
16KB
|
614 lines
/*
* DLGBOX.C
*
* Written on 10-Jul-94 by John Dennis and released to the public domain.
*
* DialogBox Code. Also includes the system HotSpot code.
*
*
* A dialog box consists of the main dlgbox structure, which defines
* colours and window position and the like, plus the dialog controls
* themselves (buttons, fields etc). Each control has a corresponding
* HotSpot and ID, which allows any mouse press/release/movement to be
* related to a hotspot and corresponding control ID. Other hotspots
* may be in the system, but note that if a hotspot is associated with
* a window, it will only be looked at if that window is current (on top).
*
* This windowing system is NOT event based in the same manner as
* Windows. It's done this way to make non-event based programs easily
* portable to this system; and as a result flexibility suffers. If you
* want to add new types, you will have to recompile the affected
* modules.
*
* Caveats: If a new ctrl type is wanted, it MUST be added here if it
* is to be processed by/for the DoDialog function. You must also
* add the display function somwhere & link it in.
* Functions to lookout for (that need mods):
* DoDialog();
* ShowCtrl();
* DoCursor();
* GetYCoord();
* BuildDialogHot();
*
*/
#define DLGBOX
#include "unused.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "winsys.h"
#include "menu.h"
#include "keys.h"
void BuildDialogHot(dlgbox * db, HotGroup * hot);
/*
**
** Global vars used by all functions.
**
*/
static int Focus = -1;
static int OldFocus = -1;
/*
**
** The Functions themselves.
**
*/
/* void *SetFocus(int id, int wid);
**
** Returns the ctrl associated with the
** id and wid. Not used currently...
*
void *SetFocus(int id, int wid)
{
int gr, it;
for (gr = 0; gr < NumHots; gr++)
{
if (!wid || HotSpot[gr]->wid == wid)
{
for (it = 0; it < HotSpot[gr]->num; it++)
{
if (HotSpot[gr]->harr[it].id == id)
{
return (void *) HotSpot[gr]->harr[it].ctl;
}
}
}
}
return NULL;
}
*/
/* int DoEditField(int *p1, int *p2, editf *i, int wid)
**
** A dummy MnuGetMsg used when an edit feild has focus,
** it handles all the msgs it understands and passes others
** back to the DoDialog() procedure.
*/
int DoEditField(EVT * event, editf * i, unsigned long wid)
{
int ret;
int pos = i->curpos;
unused(wid);
ret = WGetLine(i->x, i->y, i->len, i->buf, i->sattr, &pos, 1, 0, 0, event);
i->curpos = pos;
return ret;
}
/* static void ShowCtrl(ctrl *i, unsigned char sel);
**
** Shows a dialog box controls. Also used to show
** whether a control has been selected or not.
*/
static void ShowCtrl(ctrl * i, unsigned char sel)
{
switch (i->type)
{
case D_EDT:
((editf *) i->ctl)->select = sel;
ShowEditField((editf *) i->ctl);
break;
case D_BUT:
((button *) i->ctl)->select = sel;
ShowButton((button *) i->ctl);
break;
case D_CHK:
((ckbutton *) i->ctl)->select = sel;
ShowCkbutton((ckbutton *) i->ctl);
break;
case D_TXT:
D_ShowTxt((textl *) i->ctl);
break;
case D_WBX:
D_ShowWBox((wbox *) i->ctl);
break;
default:
break;
}
}
/* void DoCursor(dlgbox *db, int foc);
**
** Handles the placement of the cursor, if needed.
**
*/
void DoCursor(dlgbox * db, int foc)
{
if (!db)
{
TTCurSet(0);
return;
}
switch (db->ctrls[foc].type)
{
case D_CHK:
Wgotoxy(((ckbutton *) db->ctrls[foc].ctl)->x + 2, ((ckbutton *) db->ctrls[foc].ctl)->y);
TTCurSet(1);
break;
default:
TTCurSet(0);
break;
}
}
int ValidCtrl(int type)
{
switch (type)
{
case D_WBX:
case D_TXT:
return 0;
default:
return 1;
}
}
int GetPrevCtrl(dlgbox * db, int cur)
{
int foc = cur;
if ((--foc) < 0)
foc = db->num - 1;
while (foc != cur && !ValidCtrl(db->ctrls[foc].type))
{
if ((--foc) < 0)
foc = db->num - 1;
}
return foc;
}
int GetNextCtrl(dlgbox * db, int cur)
{
int foc = cur;
if ((++foc) == db->num)
foc = 0;
while (foc != cur && !ValidCtrl(db->ctrls[foc].type))
{
if ((++foc) == db->num)
foc = 0;
}
return foc;
}
int GetYCoord(ctrl * i)
{
switch (i->type)
{
case D_BUT:
return ((button *) i->ctl)->y;
case D_CHK:
return ((ckbutton *) i->ctl)->y;
case D_EDT:
return ((editf *) i->ctl)->y;
default:
return 0;
}
}
int GetRightCtrl(dlgbox * db, int cur, int num)
{
int y = GetYCoord(&db->ctrls[cur]);
int i;
for (i = cur + 1; i < num; i++)
{
if (GetYCoord(&db->ctrls[i]) == y && ValidCtrl(db->ctrls[i].type))
return i;
}
for (i = 0; i < cur; i++)
{
if (GetYCoord(&db->ctrls[i]) == y && ValidCtrl(db->ctrls[i].type))
return i;
}
return cur;
}
int GetLeftCtrl(dlgbox * db, int cur, int num)
{
int y = GetYCoord(&db->ctrls[cur]);
int i;
for (i = cur - 1; i >= 0; i--)
{
if (GetYCoord(&db->ctrls[i]) == y && ValidCtrl(db->ctrls[i].type))
return i;
}
for (i = num; i > cur; i--)
{
if (GetYCoord(&db->ctrls[i]) == y && ValidCtrl(db->ctrls[i].type))
return i;
}
return cur;
}
int GetFocus(dlgbox * db, int id)
{
int i;
for (i = 0; i < db->num; i++)
if (db->ctrls[i].id == id)
return i;
return -1;
}
/* int DoDialog(dlgbox *db, int wnd);
**
** Process a dialogbox structure (dlgbox), incorporating
** mouse and keyboard support. If there are buttons,
** it returns when one is pressed & returns the ID of the
** button.
**
** params: db - dialogbox structure to process
** wnd - use already open window?
**
** caveats: none?
*/
int DoDialog(dlgbox * db, int wnd)
{
WND *hWnd, *hCurr;
HotGroup Hot;
int WAttr = db->fattr;
int BAttr = db->battr;
int done = 0; /* terminate condition */
int i; /* loop var */
int select = 0;
int ret = 0;
int NewFoc;
EVT event;
int Msg; /* Key/Mou press */
if (!wnd)
{
hCurr = Wtop();
if ((hWnd = WndOpen(db->x1, db->y1, db->x2, db->y2, db->btype, BAttr, WAttr)) == NULL)
{
WCurr(hCurr);
return ERROR;
}
}
else
hWnd = Wtop();
if (db->title)
WTitle(db->title, BAttr);
for (i = 0; i < db->num; i++)
{
ShowCtrl(&db->ctrls[i], 0);
}
BuildDialogHot(db, &Hot);
PushHotGroup(&Hot);
Focus = 0;
ShowCtrl(&db->ctrls[Focus], 1);
DoCursor(db, Focus);
TTClearQue(); /* clear input queue */
while (!done)
{
OldFocus = Focus;
/* prolly put a switch here */
if (db->ctrls[Focus].type == D_EDT)
Msg = DoEditField(&event, (editf *) db->ctrls[Focus].ctl, hWnd->wid);
else
Msg = MnuGetMsg(&event, hWnd->wid);
switch (event.msgtype)
{
case WM_COMMAND: /* Item pressed */
if ((NewFoc = GetFocus(db, event.id)) != -1)
{
switch (Msg)
{
case LMOU_CLCK:
Focus = NewFoc;
if (db->ctrls[Focus].type != D_EDT)
select = TRUE;
break;
case MOU_LBTDN:
Fo